"""
__author__ = 'heyin'
__date__ = '2018/11/8 13:54'
练习特征工程相关内容，如特征抽取，特征预处理，特征选择，pca降维
"""
import random
import string
import jieba
import numpy as np

from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.feature_selection import VarianceThreshold
from sklearn.decomposition import PCA
from pyecharts import Scatter


def dictvec():
    """征抽取之字典特征值化，使用的是one-hot编码"""
    # 组织字典数据
    datas = list()
    num = list(range(1, 100))
    citys = ['上海', 'beijing', 'zhengzhou', 'shenzhen', 'nanjing', 'xian', 'taiyuan', 'guangzhou', 'hangzhou', 'haerbin']
    for i in range(200):
        city = random.choice(citys)  # 如果此处过多，可能造成不便(特征过多)，针对的是字符串数据
        age = random.choice(num)
        weight = random.choice(num)
        #datas.append({'city': [city, random.choice(citys)], 'age': age, 'weight': weight, 'id': i})
        datas.append({'city': [city, random.choice(citys)]})
    print(datas)
    # 创建dv对象
    dv = DictVectorizer(sparse=False)  # 不使用稀疏矩阵
    ret = dv.fit_transform(datas)
    print(ret)  # 如果是稀疏矩阵，通过toarray()转为普通数组
    # ['age', 'city=beijing', 'city=guangzhou', 'city=haerbin', 'city=hangzhou', 'city=nanjing', 'city=shenzhen',
    # 'city=taiyuan', 'city=xian', 'city=zhengzhou', 'city=上海', 'weight']
    print(dv.get_feature_names())


def textcount():
    """英文文本特征抽取，仅统计数量，不考虑重要性"""
    # 组织数据
    news = [
        'this is my car car car',
        'this is not my bike'
    ]
    cv = CountVectorizer()
    ret = cv.fit_transform(news)
    print(cv.get_feature_names())
    print(ret.toarray())


def chinesecount():
    """中文文本抽取，仅统计数量"""
    onews = [
        '就在6月22日，国务院发布任免国家工作人员名单时，林锐被任命为公安部部长助理。值得注意的是，当时他还被委派了一个重要“兼职”——网络安全保卫局党委书记、局长。',
        '简历显示，林锐1967年8月生，福建闽侯人，1994年4月加入中国共产党，1989年8月参加工作，中国人民警官大学计算机及应用专业毕业，大学学历，工学学士学位。',
        '专业是计算机应用，而工作后林锐也曾长期从事网络安全工作。从警近30年的林锐，在调任泉州市副市长、市公安局局长之前，先后担任福建省公安厅公共信息网络安全监察处副处长、泉州市公安局副局长（挂职）、福建省公安厅网络安全保卫总队总队长。',
        '2011年8月，林锐担任泉州市政府副市长、市公安局局长；2013年10月，任厦门市政府市长助理、市公安局局长；2015年5月任厦门市副市长、市公安局局长。'
    ]
    # 先进行分词处理
    nnews = list()
    for new in onews:
        n = ' '.join(jieba.cut(new))
        nnews.append(n)
    cv = CountVectorizer()
    ret = cv.fit_transform(nnews)
    print(cv.get_feature_names())
    print(ret.toarray())


def tfidf():
    """tf-idf进行词汇重要性统计"""
    onews = [
        'this is my car car car',
        'this is not my bike'
    ]
    # 先进行分词处理
    # nnews = list()
    # for new in onews:
    #     n = ' '.join(jieba.cut(new))
    #     nnews.append(n)

    tv = TfidfVectorizer(norm=None, smooth_idf=False)
    ret = tv.fit_transform(onews)

    print(tv.get_feature_names())
    print(len(tv.get_feature_names()))  # 73个特征
    print(ret.toarray())


def plot(d, name):
    print(type(d))
    v1 = d[:, 0]
    v2 = d[:, 1]
    print(v1, v2)
    scatter = Scatter("散点图示例")
    scatter.add("A", v1, v2)
    scatter.render(path=name)


def minmax():
    """归一化处理"""
    # 准备数据
    d = [
        [100, 3],
        [200, 6],
        [1500, 10]
    ]
    mm = MinMaxScaler()
    ret = mm.fit_transform(d)
    print(ret)
    # plot(d, 'moren.html')
    plot(ret, 'minmax.html')


def std():
    """标准化处理"""
    d = [
        [100, 3],
        [200, 6],
        [1500, 10]
    ]
    ss = StandardScaler()
    ret = ss.fit_transform(d)
    print(ret)
    plot(ret, 'std.html')


def nan():
    """缺失值处理"""
    im = SimpleImputer()
    d = [
        ['nan', 2, False],
        [2, 'NaN', 4],
        [np.nan, None, 1]
    ]
    ret = im.fit_transform(d)
    print(ret)


def feature_select():
    """特征选择，方差阈值 过滤式降维，过滤掉低方差特征，如方差为0的特征"""
    d = [
        [1, 2, 3],
        [1, 3, 4],
        [2, 4, 5]
    ]
    vt = VarianceThreshold(threshold=0.3)  # 0.3时，会将第一个特征过滤掉，1时，会报错，因为所有特征都被过滤了
    ret = vt.fit_transform(d)
    print(ret)
    r = ret[:, 0].var()  # 第一列的方差值为0.2222.....
    print(r)


def pca():
    """pca降维示例，针对特征较多的情况，需要对特征值进行标准化，因为受方差影响较大"""
    data = [
        [1, 2, 3, 4, 533],
        [2, 4, 1, 5, 622],
        [1, 2, 4, 3, 881],
        [5, 8, 9, 22, 112]
    ]
    p = PCA(n_components=4)
    ret = p.fit_transform(data)
    print(ret)


if __name__ == '__main__':
    dictvec()
    # textcount()
    # chinesecount()
    # tfidf()
    # minmax()
    # std()
    # nan()
    # feature_select()
    # pca()
    pass
